#-coding=utf-8
import time
import re
import subprocess
import os
import cookielib
import urllib2
import urllib
import hashlib
import hmac
import base64
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def die(string):
    print(string)
    exit()

class IAUTH():
    def __init__(self,appId,appSecret,accessURL,getuidURL,accessToken='',accessSecret='',rpId='',rpSecret='',timeOffset=0):
        self.APP_ID = appId
        self.APP_SECRET = appSecret
        self.ACCESS_URL = accessURL
        self.GETUID_URL = getuidURL
        self.ACCESS_TOKEN = accessToken
        self.ACCESS_SECRET = accessSecret
        self.RP_ID = rpId
        self.RP_SECRET = rpSecret
        self.TIME_OFFSET=timeOffset

    def __signature(self, baseStr, secret, method='HMAC-SHA1' ):
        import urllib
        import hashlib
        import hmac
        import base64
        if method=='MD5':
            m=hashlib.md5()
            m.update( baseStr +'&'+ secret )
            myhash = m.hexdigest()
            return myhash
            # print(myhash)
            # exit()
        signature = urllib.quote(
            base64.b64encode(
                hmac.new(secret, baseStr, digestmod=hashlib.sha1).digest()
                ))
        return signature

    def __hash(self, string ):
        m=hashlib.md5()
        m.update( string )
        myhash = m.hexdigest()
        return myhash

    def Auth(self,verifier,state='',ip=''):
        match = re.search('[0-9a-zA-Z]{16}',verifier)
        if not match:
            die('invalid verifier')
        now = int(time.time())+self.TIME_OFFSET
        params = [
            ('appid',self.APP_ID),
            ('time',now),
            ('sigmethod','HMAC-SHA1'),
            ('version','2.0'),
            ('verifier',verifier)]
	if state != '':params.append(('state',state))
	if ip != '':params.append(('ip',ip))
        params.sort()
        baseStr = 'GET'+'&'+self.ACCESS_URL+'&'+'&'.join(['%s=%s' % (k, v) for k, v in params])
        # print(baseStr)
        signature = self.__signature(baseStr,self.APP_SECRET)
        # print(signature)
        params.append(('sig',signature))
        header = ','.join(['%s="%s"' % (k, v) for k, v in params])
        # print(header)
        # exit()
        request = urllib2.Request( self.ACCESS_URL )
        request.add_header( 'Authorization', header )
        opener = urllib2.build_opener()
        loginResponse = opener.open(request)
        # print (loginResponse.geturl())
        print (loginResponse.read())

    def Login( self, verifier ):
        match = re.search('[0-9a-zA-Z]{16}',verifier)
        if not match:
            die('invalid verifier')
        now = int(time.time())+self.TIME_OFFSET
        params = [
            #('ip','127.0.0.1'),
            ('appid',self.APP_ID),
            ('time',now),
            ('sigmethod','HMAC-SHA1'),
            ('version','2.0'),
            ('verifier',verifier)]
        params.sort()
        baseStr = 'GET'+'&'+self.GETUID_URL+'&'+'&'.join(['%s=%s' % (k, v) for k, v in params])
        # print(baseStr)
        signature = self.__signature( baseStr, self.APP_SECRET )
        # print(signature)
        params.append(('sig',signature))
        header = ','.join(['%s="%s"' % (k, v) for k, v in params])
        # print(header)
        # exit()
        request = urllib2.Request( self.GETUID_URL )
        request.add_header( 'Authorization', header )
        opener = urllib2.build_opener()
        loginResponse = opener.open(request)
        # print (loginResponse.geturl())
        print (loginResponse.read())

    def Getdata( self, access_token, access_secret, url, params ):
        now = int(time.time())+self.TIME_OFFSET
        import string,random
        nonce = ''.join(random.sample(string.ascii_letters + string.digits, 16))
        myhash = self.__hash( '&'.join(['%s=%s' % (k, v) for k, v in params]) )
        headerParams=[
            ('appid',self.APP_ID),
            ('time',now),
            ('sigmethod','HMAC-SHA1'),
            ('version','2.0'),
            ('nonce',nonce),
            ('token',access_token),
            ('hashmethod','MD5'),
            ('hash',myhash)]
        headerParams.sort()
        # print(params)
        baseStr = 'POST'+'&'+url+'&'+'&'.join(['%s=%s' % (k, v) for k, v in headerParams])
        # print(baseStr)
        signature = self.__signature( baseStr, self.APP_SECRET+'&'+access_secret )
        # print(signature)
        headerParams.append(('sig',signature))
        header = ','.join(['%s="%s"' % (k, v) for k, v in headerParams])
        # print(header)
        postData = urllib.urlencode(params)
        request = urllib2.Request( url, postData )
        request.add_header( 'Authorization', header )
        opener = urllib2.build_opener()
        loginResponse = opener.open(request)
        # print (loginResponse.geturl())
        return (loginResponse.read())



if __name__=="__main__":
    try:
        if len(sys.argv)==3:
            IC=IAUTH('31255bdb211fd4ad', 'e1a22daa2a864be7cc0a2471142e17a4', "http://i.buaa.edu.cn/plugin/iauth/access.php", "http://i.buaa.edu.cn/plugin/iauth/getuid.php",timeOffset=0)
            if (sys.argv[1]=="auth") and (len(sys.argv[2])==16):
                verifier = sys.argv[2]
                IC.Auth( verifier,'stringLengthIs16' )
                exit()

            if (sys.argv[1]=="login") and (len(sys.argv[2])==16):
                verifier = sys.argv[2]
                IC.Login( verifier );
                exit()

            if (len(sys.argv[1])==40) and (len(sys.argv[2])==32):
                access_token = sys.argv[1]
                access_secret = sys.argv[2]
                data = IC.Getdata( access_token, access_secret, 'http://i.buaa.edu.cn/plugin/iauthClient/api/do_getallthings.php', params=[])
                print ( data )
                exit()

        print "Please check source code to see how to use"

    except Exception,e:
        print e# .read()
